package com.cooldatasoft.web.cms.person;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletContext;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.upload.FileUpload;
import org.apache.wicket.markup.html.form.upload.FileUploadField;
import org.apache.wicket.markup.html.image.ContextImage;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.util.file.Files;
import org.apache.wicket.util.file.Folder;
import org.apache.wicket.util.lang.Bytes;

import com.cooldatasoft.app.WOCApplication;
import com.cooldatasoft.app.WOCSession;
import com.cooldatasoft.base.BaseViewPage;
import com.cooldatasoft.data.Node;
import com.cooldatasoft.data.Person;
import com.cooldatasoft.data.PersonNodeMapping;
import com.cooldatasoft.data.PersonProperty;
import com.cooldatasoft.data.PersonPropertyValue;
import com.cooldatasoft.data.WorkExp;
import com.cooldatasoft.data.WorkExpProperty;
import com.cooldatasoft.data.WorkExpPropertyValue;
import com.cooldatasoft.data.custom.PersonPageData;
import com.cooldatasoft.data.custom.PersonPropertyKeyValue;
import com.cooldatasoft.data.custom.WorkExpPropertyKeyValue;


public class CreatePersonPage extends BaseViewPage {

	private PersonPageData personPageData = new PersonPageData();
	private FeedbackPanel feedbackPanel;
	

	public CreatePersonPage(Integer entityId) {
		setEntityId(entityId);
		initVariables();
		initPage();
	}
	public CreatePersonPage(){
		initVariables();
		initPage();
	}
	public CreatePersonPage(PersonPageData personPageData){
		this.personPageData = personPageData;
		initPage();
	}

	MarkupContainer container;
	MarkupContainer header;
	ExternalLink companyWebsiteLink;
	
	MarkupContainer imageDiv;
	ContextImage personImage;
	
	private void initPage() {
		
		
		container= new WebMarkupContainer("container");		
		header = new WebMarkupContainer("header");
		companyWebsiteLink = new ExternalLink("companyWebsiteLink","http://www.cooldatasoft.com","Company Name");
		companyWebsiteLink.add(new AttributeModifier("target",true,new Model("_blank")));
		header.add(companyWebsiteLink);
		container.add(header);
		
		
		imageDiv = new WebMarkupContainer("imageDiv");
		
		String imagePath = "test2.jpg"; //default no image path
		String modelImagePath = personPageData.getNewPerson().getImagePath();
		if(modelImagePath != null && modelImagePath.trim().length()>0){
			imagePath = modelImagePath;
		}		 
		personImage = new ContextImage("personImage",new Model( "img/person/"+imagePath));
		personImage.setOutputMarkupId(true);
//		ResourceReference resourceReference = new ResourceReference(imagePath);
//		Image personImage1 = new Image("personImage1",resourceReference);
		
		imageDiv.add(personImage);
		ImageUploadForm imageUploadForm = new ImageUploadForm("imageUploadForm");
//		imageUploadForm.add(new AjaxEventBehavior("onSubmit") {
//			private static final long serialVersionUID = 1L;
//            @Override
//            protected void onEvent(AjaxRequestTarget target) {	           	
//            	personImage.setModel(new Model( "img/person/"+personPageData.getNewPerson().getImagePath()));  
//            	target.addComponent(personImage);
//            }
//        });
				     
		     
		     
		
		imageDiv.add(imageUploadForm);
		container.add(imageDiv);
		
		MarkupContainer wrapper = new WebMarkupContainer("wrapper");
		MarkupContainer personalInfoDiv = new WebMarkupContainer("personalInfoDiv");
		PersonalInfoForm personalInfoForm = new PersonalInfoForm("personalInfoForm");
		personalInfoDiv.add(personalInfoForm);
		wrapper.add(personalInfoDiv);
		
		MarkupContainer workExperienceAddDiv = new WebMarkupContainer("workExperienceAddDiv");
		WorkExperienceAddForm workExperienceAddForm = new WorkExperienceAddForm("workExperienceAddForm");
		workExperienceAddDiv.add(workExperienceAddForm);
		
		
		MarkupContainer workExperienceDiv = new WebMarkupContainer("workExperienceDiv");
		Label workExperienceTitle= new Label("workExperienceTitle","Work Experience");
		
		ListView workExperienceList = new ListView("workExperienceList", new PropertyModel(this,"personPageData.workExperienceList")) {
		    protected void populateItem(final ListItem item) {
		    	List<WorkExpPropertyKeyValue> workExpListItem = (List<WorkExpPropertyKeyValue>) item.getModelObject();
		    	
		    	
	    		final ListView work = new ListView("work", item.getModel()) {
					@Override
					protected void populateItem(ListItem item2) {
						Label keyLabel = new Label("key", new PropertyModel(item2.getModel(),"workExpProperty.label"));
						Label valueLabel = new Label("value", new PropertyModel(item2.getModel(),"workExpPropertyValue.value"));
						keyLabel.setRenderBodyOnly(true);
						valueLabel.setRenderBodyOnly(true);				
						item2.add(keyLabel);
						item2.add(valueLabel);
					}
				};					
				item.add(work);
				
				Link deleteLink = new Link("deleteLink"){
					@Override
					public void onClick() {
						List<WorkExpPropertyKeyValue> workExpToBeDeleted = (List<WorkExpPropertyKeyValue>) item.getModelObject();
						
						boolean workExpSaved=false;
						for (Iterator<WorkExpPropertyKeyValue> iterator = workExpToBeDeleted.iterator(); iterator.hasNext();) {
							WorkExpPropertyKeyValue workExpPropertyKeyValue = iterator.next();
							
							WorkExp workExpDeleted = workExpPropertyKeyValue.getWorkExp();
							WorkExpPropertyValue workExpPropertyValueDeleted = workExpPropertyKeyValue.getWorkExpPropertyValue();
							
							if(workExpDeleted.getId() == null){
								//if not persisted to DB, just remove it from the arraylist
								CreatePersonPage.this.personPageData.getWorkExperienceList().remove(workExpToBeDeleted);	
								break;
							}else{
								workExpDeleted.setUpdateDate(new Date());
								workExpDeleted.setUpdateUserId(WOCSession.get().getUser().getId());
								workExpDeleted.setDeleted(true);
							}
							
							workExpPropertyValueDeleted.setUpdateDate(new Date());
							workExpPropertyValueDeleted.setUpdateUserId(WOCSession.get().getUser().getId());
							workExpPropertyValueDeleted.setDeleted(true);
							
							if(!workExpSaved){
								WOCApplication.get().getWorkServiceProxy().saveOrUpdate(workExpDeleted);
							}
							WOCApplication.get().getWorkServiceProxy().saveOrUpdate(workExpPropertyValueDeleted);
						}
					}					
				};
				item.add(deleteLink);
				
				if(workExpListItem.size()>0 && workExpListItem.get(0).getWorkExp().getDeleted()){
					item.setVisible(false);
				}
		    	
		    }
		};
		
		workExperienceDiv.add(workExperienceList);
		workExperienceDiv.add(workExperienceTitle);
		
		
		container.add(workExperienceAddDiv);
		container.add(workExperienceDiv);
		container.add(imageDiv);
		container.add(wrapper);
		
		add(container);
	}
	

	public void initVariables(){
		
		if(getEntityId()==null ){
			personPageData.getNewPerson().setCreateUserId(WOCSession.get().getUser().getId());
		}else{
			Person person = WOCApplication.get().getPersonServiceProxy().get(getEntityId());
			personPageData.setNewPerson(person);
		}
		initPersonProperty(getEntityId());
		initWorkExpProperty(getEntityId());
	}
	
	private void initPersonProperty(Integer personId) {
		List<PersonProperty> personPropertyList = WOCApplication.get().getPersonServiceProxy().getPersonPropertyList();
		personPageData.setPersonalDataList(new ArrayList<PersonPropertyKeyValue>());
		for (Iterator<PersonProperty> iterator = personPropertyList.iterator(); iterator.hasNext();) {
			PersonProperty personProperty = iterator.next();
			if(personId==null ){
				personPageData.getPersonalDataList().add(new PersonPropertyKeyValue(personProperty,new PersonPropertyValue()));
			}else{
				PersonPropertyValue value = WOCApplication.get().getPersonServiceProxy().getPersonPropertyValue(personId, personProperty.getId());
				personPageData.getPersonalDataList().add(new PersonPropertyKeyValue(personProperty,value));
			}
						
		}
	}

	private void initWorkExpProperty(Integer personId) {
		
		List<WorkExpProperty> workExpPropertyList = initWorkExpAddForm();
		
		personPageData.setWorkExperienceList(new ArrayList<List<WorkExpPropertyKeyValue>>());
		if(personId!=null){
			List<WorkExp> workExpList = WOCApplication.get().getWorkServiceProxy().getWorkExpListByPersonId(personId);
			//Iterate over Work Exp.
			for (Iterator<WorkExp> iterator = workExpList.iterator(); iterator.hasNext();) {
				WorkExp tbWorkExp = iterator.next();
				List<WorkExpPropertyKeyValue> workExpDetails = new ArrayList<WorkExpPropertyKeyValue>();
				//For each work exp. set values 
				for (Iterator<WorkExpProperty> iterator2 = workExpPropertyList.iterator(); iterator2.hasNext();) {
					WorkExpProperty tbWorkExpProperty = iterator2.next();
					WorkExpPropertyValue tbWorkExpPropertyValue = 
						WOCApplication.get().getWorkServiceProxy().getWorkExpPropertyValue(tbWorkExp.getId(), tbWorkExpProperty.getId());
					workExpDetails.add(new WorkExpPropertyKeyValue(tbWorkExp,tbWorkExpProperty,tbWorkExpPropertyValue));
				}				
				personPageData.getWorkExperienceList().add(workExpDetails);
			}
		}
		
		
	}

	private List<WorkExpProperty> initWorkExpAddForm() {
		List<WorkExpProperty> workExpPropertyList = WOCApplication.get().getWorkServiceProxy().getWorkExpPropertyList();	
		personPageData.setWorkExpDataList(new ArrayList<WorkExpPropertyKeyValue>());		
		WorkExp tbWorkExp = new WorkExp();
		for (Iterator<WorkExpProperty> iterator = workExpPropertyList.iterator(); iterator.hasNext();) {
			WorkExpProperty workExpProperty = iterator.next();
			personPageData.getWorkExpDataList().add(new WorkExpPropertyKeyValue(tbWorkExp,workExpProperty,new WorkExpPropertyValue()));						
		}
		return workExpPropertyList;
	}
	
	
	
	class PersonalInfoForm extends Form{

		
		
		public PersonalInfoForm(String id) {
			super(id);
			
			ListView listview = new ListView("personalInfoList", new PropertyModel(CreatePersonPage.this,"personPageData.personalDataList")) {
				@Override
				protected void populateItem(ListItem item) {
					Label keyLabel = new Label("key", new PropertyModel(item.getModel(),"personProperty.label"));
					PersonProperty personProperty =  ((PersonPropertyKeyValue) item.getModelObject()).getPersonProperty();
					
					TextField valueLabel = new TextField("value");
					DropDownChoice dropDownChoiceValueLabel = new DropDownChoice("valueSelect");
					List<Node> departmentList = new ArrayList<Node>();
					if(personProperty.getCombo()){
						valueLabel.setVisible(false);
						departmentList = WOCApplication.get().getNodeServiceProxy().getNodeListRemoveRootAndCEO();	
						
						ChoiceRenderer choiceRenderer = new ChoiceRenderer("label", "id");						
						dropDownChoiceValueLabel.setChoiceRenderer(choiceRenderer);
						dropDownChoiceValueLabel.setChoices(departmentList);
						dropDownChoiceValueLabel.setModel(new PropertyModel(item.getModel(),"comboObject"));
					}else{
						valueLabel.setModel(new PropertyModel(item.getModel(),"personPropertyValue.value"));
						dropDownChoiceValueLabel.setVisible(false);
					}
										
					keyLabel.setRenderBodyOnly(true);
					item.add(keyLabel);
					item.add(dropDownChoiceValueLabel);
					item.add(valueLabel);
				}
			};		
			Button personalInfoSaveButton = new Button("personalInfoSaveButton");
			add(personalInfoSaveButton);
			add(listview);
			
		}

		@Override
		protected void onSubmit() {
			try{
				List<PersonPropertyKeyValue> personPropertyKeyValueList = CreatePersonPage.this.personPageData.getPersonalDataList();
				
				for (Iterator<PersonPropertyKeyValue> iterator = personPropertyKeyValueList.iterator(); iterator.hasNext();) {
					PersonPropertyKeyValue personPropertyKeyValue = iterator.next();
					if(personPropertyKeyValue.getPersonProperty().getCombo()){
						Node selectedNode = (Node) personPropertyKeyValue.getComboObject();
					
						if(CreatePersonPage.this.personPageData.getNewPerson().getId() == null){
							CreatePersonPage.this.personPageData.getNewPerson().setUpdateDate(new Date());
							CreatePersonPage.this.personPageData.getNewPerson().setUpdateUserId(WOCSession.get().getUser().getId());
							WOCApplication.get().getPersonServiceProxy().saveOrUpdate(CreatePersonPage.this.personPageData.getNewPerson());
						}
						
						PersonNodeMapping mapping = 
							WOCApplication.get().getNodeServiceProxy().getPersonNodeMappingByPersonId(CreatePersonPage.this.personPageData.getNewPerson().getId());
						if(mapping == null){
							mapping = new PersonNodeMapping();
							mapping.setCreateUserId(WOCSession.get().getUser().getId());
							mapping.setPersonId(CreatePersonPage.this.personPageData.getNewPerson().getId());
						}																		
						mapping.setUpdateUserId(WOCSession.get().getUser().getId());
						mapping.setUpdateDate(new Date());
						mapping.setNodeId(selectedNode.getId());
						
						WOCApplication.get().getNodeServiceProxy().saveOrUpdate(mapping);
						
					}else{
						PersonPropertyValue tbPersonPropertyValue = personPropertyKeyValue.getPersonPropertyValue();
						tbPersonPropertyValue.setUpdateDate(new Date());
						tbPersonPropertyValue.setCreateUserId(WOCSession.get().getUser().getId());
						tbPersonPropertyValue.setUpdateUserId(WOCSession.get().getUser().getId());
						tbPersonPropertyValue.setDeleted(false);
						if(CreatePersonPage.this.personPageData.getNewPerson().getId() == null){
							CreatePersonPage.this.personPageData.getNewPerson().setUpdateDate(new Date());
							CreatePersonPage.this.personPageData.getNewPerson().setUpdateUserId(WOCSession.get().getUser().getId());
							WOCApplication.get().getPersonServiceProxy().saveOrUpdate(CreatePersonPage.this.personPageData.getNewPerson());
						}
						tbPersonPropertyValue.setPersonId(CreatePersonPage.this.personPageData.getNewPerson().getId());
						tbPersonPropertyValue.setPersonPropertyId(personPropertyKeyValue.getPersonProperty().getId());
						WOCApplication.get().getPersonServiceProxy().saveOrUpdate(tbPersonPropertyValue);
					}
				}			
				WOCApplication.get().getWorkServiceProxy().saveOrUpdate(personPageData.getWorkExperienceList(),WOCSession.get().getUser(),personPageData.getNewPerson());
				WOCApplication.get().getPersonServiceProxy().saveOrUpdate(personPageData.getNewPerson());
				
				
			}catch(Exception e){
				feedbackPanel.error("An error occured! Please try again.");
				e.printStackTrace();
			}
			feedbackPanel.info("Saved.");
			setResponsePage(PersonListPage.class);
		}
	}
	
	/**
	 * Used for uploading images to system.
	 * @author fatih mehmet ucar
	 *
	 */
	class ImageUploadForm extends Form {

		private FileUploadField fileUploadField;
		private FeedbackPanel uploadFeedback;
		private UploadProgressBar uploadProgressBar;
		
		public ImageUploadForm(String name) {
			super(name);
			
			setMultiPart(true);
			setMaxSize(Bytes.kilobytes(WOCApplication.MAX_FILE_SIZE_KB));
			
			fileUploadField = new FileUploadField("fileInput");
			uploadFeedback = new FeedbackPanel("uploadFeedback");
			// Add upload form with ajax progress bar
			uploadProgressBar = new UploadProgressBar("progress",this);
			
			feedbackPanel = uploadFeedback;
			
			add(fileUploadField);
			add(uploadProgressBar);
			add(uploadFeedback);
		}

		/**
		 * Check if there is already a file with same name. 
		 * @param newFile
		 */
		private void checkFileExists(File newFile) {
			if (newFile.exists()) {
				if (!Files.remove(newFile)) {
					throw new IllegalStateException("Unable to overwrite "+ newFile.getAbsolutePath());
				}
			}
		}

		private Folder getUploadFolder() {
			ServletContext context = ((WebApplication) getApplication()).getServletContext(); 
			File imgFolder = new File(context.getRealPath("/img/person/")); 
			
			if(!imgFolder.exists()){
				imgFolder.mkdirs();
			}
			
			return new Folder(imgFolder);
		}

		protected void onSubmit() {
			final FileUpload upload = fileUploadField.getFileUpload();
			if (upload != null) {
				// Create a new file
				File newFile = new File(getUploadFolder(), upload.getClientFileName());

				// Check new file, delete if it already exists
				checkFileExists(newFile);
				try {
					// Save to new file
					newFile.createNewFile();
					upload.writeTo(newFile);
					
					CreatePersonPage.this.personPageData.getNewPerson().setImagePath(newFile.getName());
					CreatePersonPage.this.personPageData.getNewPerson().setUpdateDate(new Date());
					CreatePersonPage.this.personPageData.getNewPerson().setUpdateUserId(WOCSession.get().getUser().getId());
					
				} catch (Exception e) {
					e.printStackTrace();
					uploadFeedback.error("An error occured. Please try again.");
				}
				uploadFeedback.info("Uploaded file : "+ upload.getClientFileName()+" will not be saved until you save person!");
				setResponsePage(new CreatePersonPage(CreatePersonPage.this.personPageData));
			}
		}
	}
	 
	class WorkExperienceAddForm extends Form{

		Label workExperienceAddTitle;
		ListView workAdd;
		
		public WorkExperienceAddForm(String id) {
			super(id);

			workExperienceAddTitle= new Label("workExperienceAddTitle","Add Work Experience");

			
			workAdd = new ListView("workAdd",new PropertyModel( CreatePersonPage.this,"personPageData.workExpDataList")) {
				@Override
				protected void populateItem(ListItem item) {
					Label keyLabel = new Label("key", new PropertyModel(item.getModel(),"workExpProperty.label"));
					TextField valueLabel = new TextField("value", new PropertyModel(item.getModel(),"workExpPropertyValue.value"));
					keyLabel.setRenderBodyOnly(true);			
					item.add(keyLabel);
					item.add(valueLabel);
				}
			};		
			Button addWorkButton = new Button("addWorkButton");
			
			add(addWorkButton);
			add(workAdd);
			add(workExperienceAddTitle);
		}

		@Override
		protected void onSubmit() {			
			personPageData.getWorkExperienceList().add(personPageData.getWorkExpDataList());
			initWorkExpAddForm();
			workAdd.setModelObject(personPageData.getWorkExpDataList());
			
		}
		
		
	}
	
	public PersonPageData getPersonPageData() {
		return personPageData;
	}

	public void setPersonPageData(PersonPageData personPageData) {
		this.personPageData = personPageData;
	}
}
